package ade.prime.activity;

import ade.prime.activity.adapter.ListLessonDetailsAdapter;
import ade.prime.model.AdeWebOptions;
import ade.prime.model.Lesson;
import ade.prime.model.LessonType;
import ade.prime.model.Lessons;
import ade.prime.model.Schedule;
import ade.prime.service.AdeWebServiceListener;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.app.ProgressDialog;
import android.content.ComponentName;
import android.content.DialogInterface;
import android.content.DialogInterface.OnCancelListener;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.SimpleOnPageChangeListener;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListAdapter;
import android.widget.ListView;

import com.actionbarsherlock.app.SherlockListFragment;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuItem;

/**
 * Vue affichant les informations d'un cours (détail d'un cours).
 *
 * @author Zanette Sébastien,
 * @author Andrianjafintrimo Victor
 */
public class LessonDetails extends AdeWebFragmentActivity 
implements BundleExtraNames {

	/**
	 * Conteneur d'information de ce cours.
	 */
	protected Lesson lesson ;
	/**
	 * Index du cours courant dans la liste de cours.
	 */
	protected long idLesson ;
	/**
	 * Liste complète des cours de l'emploi du temps.
	 */
	protected Lessons lessons ;
	/**
	 * Boite de dialogue affichant un chargement lorsqu'un emploi du temps est
	 * mis à jour.
	 */
	protected ProgressDialog updateDialog;
	/**
	 * Ancienne instance du cours, utilisée pour montrer les changement lors
	 * d'un update
	 */
	protected Lesson oldS ;
	
	/**
	 * Flag pour savoir s'il y a eu un changement important de l'emploi du
	 * temps
	 */
	private boolean changement;

	protected MyAdapter mAdapter ;

	protected ViewPager mPager ;

	/**
	 * Initialise la vue.
	 * @param savedInstanceState 
	 */
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState) ;
		//Fixe le thème de la page
		this.setTheme(AdeWebOptions.getTheme(this)) ;
		//Ajoute une petite flèche à gauche du logo dans la barre d'action
		getSupportActionBar().setDisplayHomeAsUpEnabled(true) ;

		setContentView(R.layout.lesson_details) ;

		//Recupére la liste complétes des cours de l'emploi du temps passé en paramètre
		this.lessons = this.getIntentLessons() ;       
		//Séléctionne parmi la liste complète, le cours courant à afficher
		//this.lesson = this.getIntentLesson();
		//Positionne l'indice du cours courant
		this.idLesson = this.getIntent().getLongExtra(EXTRA_DISPLAYED_LESSON, 0) ;
		this.getSupportActionBar().setTitle(this.lessons.get(0).getTitle()) ;

		/*
		 * S'il y a eu un changement "important" du cours on met en valeur les
		 * changements et on repositionne le statut CHANGE car l'utilisateur
		 * vient de consulter le cours
		 */
		/* if (this.lesson.getChange() == Lesson.BIG_CHANGE) {
            //this.montrerChangement();
            this.lesson.setChange(Lesson.NO_CHANGE);
            //this.remisAZero();
        } else {
            this.changement = false;
        }
        this.setTitle(this.lesson.getTitle());*/
		this.mAdapter = new MyAdapter(getSupportFragmentManager(), this.lessons) ;
		this.mPager = (ViewPager)findViewById(R.id.lesson_details_viewpager) ;
		this.mPager.setAdapter(this.mAdapter) ;    
		this.mPager.setOnPageChangeListener(new myPageChangeListener()) ;
		this.lesson = this.lessons.get((int) this.idLesson) ;
		
		//Positionne le viewPager à la bonne page
		this.mPager.setCurrentItem((int) this.idLesson) ;
	}// onCreate(Bundle)
	
	/**
	 * {@inheritDoc}
	 * @see ade.prime.activity.AdeWebFragmentActivity#getAdeWebServiceListener()
	 */
	@Override
	protected AdeWebServiceListener getAdeWebServiceListener() {
		return new AdeWebServiceListenerAdapter(this) ;
	}// getAdeWebServiceListener()

	/**
	 * Remet à zéro après consultation du changement
	 */
	/*private void remisAZero(){
        Database db = new Database();
        db.updateStatutLesson(this.lesson.getLessonId(), this.lesson.getSchedule(), Lesson.NO_CHANGE);
        db.removeLesson_HistoryWithID(lesson.getLessonId(), lesson.getSchedule());
    }*/

	/**
	 * Affiche les boutons/options de la barre d'action.
	 */
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		menu.add("Marquer") //$NON-NLS-1$
		.setIcon(R.drawable.ic_action_edit_holo_dark)
		.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
		return super.onCreateOptionsMenu(menu);
	}

	/**
	 * Gére les actions des boutons/options de la barre d'action.
	 */
	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch(item.getItemId()) {
		case android.R.id.home:
			this.onBackPressed() ;
			break ;
		default:
			//Marque le cours (normal, important, examen)
			this.mark() ;
		}// switch
		return true ;
	}

	/**
	 * Affiche une boite de dialogue avec les choix de type de cours. Normal,
	 * Inmportant, Examen.
	 */
	private void mark() {
		LessonType currentType = this.lesson.getType() ;

		AlertDialog.Builder builder = new Builder(this) ;
		ListAdapter dialogAdapter = new ArrayAdapter<LessonType>(
				this, android.R.layout.select_dialog_singlechoice, LessonType.values()) ;
		builder.setSingleChoiceItems(dialogAdapter, currentType.ordinal(), 
				new MarkListener(this)) ;
		builder.setTitle(R.string.ViewSchedule_mark_dialog_title) ;
		builder.setIcon(RESULT_OK) ;
		builder.create().show() ;
	}// mark()

	/**
	 * Lorsqu'il y a eu un changement important dans, on récupére l'historique deu cours, et on met le flag 'changement' à vrai
	 */
	/* private void montrerChangement() {
        Database db = new Database();
        this.oldS = db.getLessonHistoryWithID(this.lesson.getLessonId(), this.lesson.getSchedule());
        this.changement = true;
    }*/

	/**
	 * OnClickListener pour le marquage d'un cour.
	 *
	 * <p>Récupère le type du cours ans met à jour la base de données.
	 *
	 * @author Schnell Michaël, Zanette Sébastien
	 */
	class MarkListener implements DialogInterface.OnClickListener {

		/**
		 * Vue contenant le composant attaché à l'écouteur.
		 */
		private LessonDetails activity;

		/**
		 * Constructeur.
		 *
		 * @param activity View containing the component attached to this
		 * listener
		 */
		public MarkListener(LessonDetails activity) {
			super();
			this.activity = activity;
		}// MarkListener(LessonDetails)

		/**
		 * Définition des action du clique sur le composant attaché.
		 *
		 * @param	actualView view of the component who has received a click
		 * event
		 */ 
//		public void onClick(DialogInterface dialog, LessonType item) {
//            Lesson dispLesson = this.container.getLesson();
//            // A new type has been selected
//            if (item != dispLesson.getType()) {
//                dispLesson.setType(item);
//                Database db = new Database();
//                db.updateLesson(dispLesson.getLessonId(), dispLesson.getSchedule(), dispLesson);
//                this.container.init();
//            }// if
//            dialog.dismiss();
//        }// onClick(DialogInterface, int)

		@Override
		public void onClick(DialogInterface dialog, int which) {
			LessonType[] lessonTypes = LessonType.values() ;
			LessonType newType = lessonTypes[which] ;
			if (!newType.equals(this.activity.lesson.getType())) {
				try {
					this.activity.serviceApi.setLessonType(
							this.activity.lesson, newType) ;
				} catch (RemoteException re) {
					Log.d(TAG, String.format("Failed to mark lesson '%s' (%s)",  //$NON-NLS-1$
							this.activity.lesson.getTitle(), 
							Long.valueOf(this.activity.lesson.getLessonId())), re) ;
				}// try
			}// if
			
			dialog.dismiss() ;			
		}// onClick(DialogInterface, int)
	}// class MarkListener

//	/**
//	 * Retourne une instance de {@code Lesson} contenant l'information sur la
//	 * lesson à afficher.
//	 */
//	private Lesson getIntentLesson() {
//		long id = this.getIntent().getLongExtra(EXTRA_DISPLAYED_LESSON,0);
//		return this.lessons.get((int)id);
//	}// getIntentLesson()

	/**
	 * Retourne une instance de {@code Lessons} contenant tous les cours de l'emploi du temps.
	 */
	private Lessons getIntentLessons() {
		return this.getIntent().getParcelableExtra(EXTRA_SCHEDULE_LESSONS);
	}// getIntentLesson()

	/**
	 * Retourne une instance de {@code Lesson} contenant l'information sur la
	 * lesson à afficher.
	 *
	 * @return	instance of {@code Lesson} containing the information about the
	 * displayed lesson
	 */
	public Lesson getLesson() {
		return this.lesson;
	}// getLesson()


	/**
	 * Parse un {@code String} formaté de groupes et retourne une liste
	 * contenant tous les groupes.
	 *
	 * @param groups formatted {@code String} of groups
	 *
	 * @return	Array containing all the groups
	 */
	public static String[] parseGroups(String groups) {
		String[] g = groups.split(","); //$NON-NLS-1$
		if(g.length == 1 && g[0].equals("")){ //$NON-NLS-1$
			g = new String[0];
		}
		return g;
	}// parseGroup(String)

	/**
	 * Parse un {@code String} formaté d'enseignant et retourne une liste
	 * contenant tous les enseignants.
	 *
	 * @param teachers chaine de caractères d'enseignant séparés par des virgules
	 * @return	Array containing all the teachers
	 */
	public static String[] parseTeachers(String teachers) {
		String[] g = teachers.split(","); //$NON-NLS-1$
		if(g.length == 1 && g[0].equals("")){ //$NON-NLS-1$
			g = new String[0];
		}
		return g;
	}// parseTeachers(String)

	/**
	 * Utilisé pour l'affichage d'une boite de dialogue lorque l'emploi du temps
	 * est en cours de mise à jour.
	 */
	/*   public void onUpdate(Object... args) {
        try {
            String scheduleName = (String) args[0];
            int scheduleState = (Integer) args[1];
            if (scheduleName.equals(this.lesson.getSchedule())) {
                if (scheduleState == UpdateManager.STATUS_UPDATING) {
                    if (this.updateDialog == null) {
                        this.updateDialog = ProgressDialog.show(this,
                                "Chargement", "Mise à jour en cours ...",
                                true, true, new UpdateCancelListener(this));
                    }// if
                } else {
                    if (this.updateDialog != null) {
                        this.updateDialog.dismiss();
                        this.updateDialog = null;
                    }// if
                }// if
            }// if
        } catch (Exception e) {

        }//try        
    }// onUpdate(Object...)
	 */

	/**
	 * OnCancelListener pour le bouton "annuler", si l'utilisateur souhaite
	 * quitter cette vue pendant que l'emploi du temps est synchronisé.
	 *
	 * @author	Schnell Michaël, Zanette Sébastien
	 */
	class UpdateCancelListener extends Object implements OnCancelListener {

		/**
		 * Vue contenant le composant attaché à l'écouteur.
		 */
		protected LessonDetails container;

		/**
		 * Constructeur.
		 *
		 * @param container View containing the component attached to this
		 * listener
		 */
		public UpdateCancelListener(LessonDetails container) {
			super();
			this.container = container;
		}// UpdateCancelListener(LessonScreen)

		/**
		 * Définition l'action annuler.
		 *
		 * @param	actualView view of the component who has received a click
		 * event
		 */
		@Override
		public void onCancel(DialogInterface dialog) {
			dialog.dismiss();
			this.container.onBackPressed();
		}// onCancel(DialogInterface)
	}// class UpdateCancelListener

	public static class MyAdapter extends FragmentStatePagerAdapter {

		private Lessons lessons;

		public MyAdapter(FragmentManager fm, Lessons lessons) {
			super(fm);
			this.lessons = lessons;
		}

		@Override
		public int getCount() {
			return this.lessons.size();
		}

		@Override
		public Fragment getItem(int position) {
			return ArrayListFragment.newInstance(position, this.lessons) ;
		}
	}

	public static class ArrayListFragment extends SherlockListFragment {
		int id;
		Lessons lessons;

		/**
		 * Create a new instance of ArrayListFragment, providing "num"
		 * as an argument.
		 */
		static ArrayListFragment newInstance(int id, Lessons lessons) {
			ArrayListFragment f = new ArrayListFragment();

			// Supply num input as an argument.
			Bundle args = new Bundle();
			args.putInt("id", id); //$NON-NLS-1$
			args.putParcelable("lessons", lessons); //$NON-NLS-1$
			f.setArguments(args);

			return f;
		}

		/**
		 * When creating, retrieve this instance's number from its arguments.
		 */
		@Override
		public void onCreate(Bundle savedInstanceState) {
			super.onCreate(savedInstanceState);
			this.id = getArguments() != null ? getArguments().getInt("id") : 1; //$NON-NLS-1$
			this.lessons = getArguments().getParcelable("lessons"); //$NON-NLS-1$
		}

		/**
		 * The Fragment's UI is just a simple text view showing its
		 * instance id.
		 */
		@Override
		public View onCreateView(LayoutInflater inflater, ViewGroup container,
				Bundle savedInstanceState) {        	
			View v = inflater.inflate(R.layout.lesson_details_pager_list, container, false);
			return v;
		}

		@Override
		public void onActivityCreated(Bundle savedInstanceState) {
			super.onActivityCreated(savedInstanceState) ;
			setListAdapter(new ListLessonDetailsAdapter(getActivity(), 
					this.lessons.get(this.id))) ;
		}

		@Override
		public void onListItemClick(ListView l, View v, int position, long itemId) {
			//TO DO
			//Clique sur la salle
			//Clique dur l'enseignant
		}
	}

	private class myPageChangeListener extends SimpleOnPageChangeListener {
		protected myPageChangeListener() {
			super() ;
		}

		@Override
		public void onPageSelected(int position) {
			LessonDetails activity = LessonDetails.this ;
			activity.lesson = activity.lessons.get(position) ;
			activity.getSupportActionBar().setTitle(activity.lesson.getTitle()) ;
		}
	}// class myPageChangeListener
	
	/**
	 * {@inheritDoc}
	 * @see ade.prime.activity.AdeWebFragmentActivity#getServiceConnection()
	 */
	@Override
	protected ServiceConnection getServiceConnection() {
		return new ServiceConnectionAdapter(this) ;
	}// getServiceConnection()
	
	private class ServiceConnectionAdapter 
	extends AdeWebFragmentActivity.ServiceConnectionAdapter {

		/**
		 * {@inheritDoc}
		 */
		protected ServiceConnectionAdapter(AdeWebFragmentActivity activity) {
			super(activity) ;
		}// ServiceConnectionAdapter(AdeWebFragmentActivity)
		
		/**
		 * {@inheritDoc}
		 */
		@Override
		public void onServiceConnected(ComponentName name, IBinder service) {
			super.onServiceConnected(name, service) ;
			// Ajout du sous-titre
			LessonDetails ld = (LessonDetails) this.activity ;
			int scheduleId = ld.lessons.get(0).getScheduleId() ;
			Schedule schedule = null ;
			try {
				schedule = ld.serviceApi.getSchedule(scheduleId) ;
				ld.getSupportActionBar().setSubtitle(schedule.getName()) ;
			} catch (RemoteException re) {
				Log.d(TAG, String.format(
						"Failed to retrieve schedule width id %d.",  //$NON-NLS-1$
						Integer.valueOf(scheduleId)), re) ;
			}// try
		}// onServiceConnected(ComponentName, IBinder)
		
	}// class ServiceConnectionAdapter
	
	private class AdeWebServiceListenerAdapter 
	extends AdeWebFragmentActivity.AdeWebServiceListenerAdapter {
		protected AdeWebServiceListenerAdapter(AdeWebFragmentActivity activity) {
			super(activity) ;
		}// AdeWebServiceListenerAdapter(AdeWebFragmentActivity)
		/**
		 * {@inheritDoc}
		 */
		@Override
		protected void handleModifiedLessonTypeRunnable(Lesson modifiedLesson) {
			LessonDetails ld = (LessonDetails) this.activity ;
			long modifiedId = modifiedLesson.getLessonId() ;
			for(Lesson l : ld.lessons) {
				if (l.getLessonId() == modifiedId) {
					l.setType(modifiedLesson.getType()) ;
					break ;
				}// if
			}// for
			ld.mAdapter.notifyDataSetChanged() ;
		}// handleModifiedLessonTypeRunnable(Lesson)
	}// class AdeWebServiceListenerAdapter

}// class LessenScreen
